package com.h2cloud.ResolvalbeType;

import org.junit.Assert;
import org.springframework.core.ResolvableType;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * @Package: com.h2cloud.ResolvalbeType
 * @ClassName: forFieldTest
 * @Author: h2cloud
 * @CreateTime: 2023/11/7 11:12 下午
 * @Description:
 */
public class forFieldTest {
	public static void main(String[] args) {
		// 1. Service<Double, Float> service
		Field filed = ReflectionUtils.findField(ResolveTypeTest.class, "service");
		ResolvableType resolvableType = ResolvableType.forField(filed);
		// getType() 保存原始的 Type 类型
		System.out.println("filed.getGenericType() = " + filed.getGenericType());
		Assert.assertEquals(filed.getGenericType(), resolvableType.getType());
		// resolve() 对于 ParameterizedType 类型保存的是 <> 之前的类型，即 Service.class
		Assert.assertEquals(((ParameterizedType) filed.getGenericType()).getRawType(), resolvableType.resolve());

		Class<?> clazz = resolvableType.getGeneric(0).resolve();
		Assert.assertEquals(Double.class, clazz);

		// 2. List<List<String>> list
		resolvableType = ResolvableType.forField(
				ReflectionUtils.findField(ResolveTypeTest.class, "list"));
		// 下面两种获取泛型的方式等价
		clazz = resolvableType.getGeneric(0).getGeneric(0).resolve();
		Assert.assertEquals(String.class, clazz);
		clazz = resolvableType.getGeneric(0, 0).resolve();
		Assert.assertEquals(String.class, clazz);

		// 3. Map<String, Map<String, Integer>> map
		resolvableType = ResolvableType.forField(
				ReflectionUtils.findField(ResolveTypeTest.class, "map"));
		clazz = resolvableType.getGeneric(1).getGeneric(1).resolve();
		Assert.assertEquals(Integer.class, clazz);

		// 4. List<String>[] array
		resolvableType = ResolvableType.forField(
				ReflectionUtils.findField(ResolveTypeTest.class, "array"));
		Assert.assertTrue(resolvableType.isArray());
		Assert.assertEquals(List.class, resolvableType.getComponentType().resolve());
		Assert.assertEquals(String.class, resolvableType.getComponentType().getGeneric(0).resolve());
	}
}
